/**
 * Created by lintao_alex on 2017/12/12.
 */



namespace game{
    import EgretArmatureDisplay = dragonBones.EgretArmatureDisplay;
    import DisplayObjectContainer = egret.DisplayObjectContainer;
    import EventObject = dragonBones.EventObject;
    import GObject = fairygui.GObject;

    export class SkeletonAutoEffect extends DisplayObjectContainer{
        protected _armatureDisplay:EgretArmatureDisplay;
        private _skeleton:string;
        private _armature:string;
        private _replaceArmature:string;

        private _playAnimation:string;
        private _playTimes:number;
        private _speed:number;

        readonly onPlayCmpCall:BackCall;
        private _onGotArmature:BackCall;

        public constructor(skeName:string, armature:string, replace?:string){
            super();
            this.onPlayCmpCall = new BackCall();
            this._skeleton = skeName;
            this._armature = armature;
            this._replaceArmature = replace;
            SkeletonManager.instance.prepareSke(skeName, this.gotRes, this);
        }

        public dispose():void{
            if(this.hasDisposed) return;
            DisplayUtils.removeFromParent(this);
            this._skeleton = null;
            if(!this._armatureDisplay) return;
            let armature = this._armatureDisplay;
            DisplayUtils.removeFromParent(armature);
            armature.dispose();
            this._armatureDisplay = null;
        }

        private gotRes(){
            if(this.hasDisposed) return;//已经销毁
            this._armatureDisplay  = SkeletonManager.instance.buildArmatureDisplay(this._armature, this._skeleton, this._replaceArmature)
            if(this._onGotArmature){
                this._onGotArmature.invoke(this._armatureDisplay, this);
            }
            this._armatureDisplay.addEventListener(EventObject.COMPLETE, this.onPlayCmp, this)
            if(this._playAnimation){
                this.animationPlay();
            }
            this.dealArmatureOnGot();
        }
        protected dealArmatureOnGot(){}

        private onPlayCmp(evt:EventObject){
            if(this.hasDisposed) return;
            if(this.onPlayCmpCall.hasCall){
                this.onPlayCmpCall.invoke(this, this._armatureDisplay);
            }else{
                DisplayUtils.removeFromParent(this._armatureDisplay);
            }
        }

        public play(animation:string='show', times:number=1, speed:number=1){
            if(this.hasDisposed) return;
            this._playAnimation = animation;
            this._playTimes = times;
            this._speed = speed;
            if(this._armatureDisplay){
                let amd = this._armatureDisplay;
                DisplayUtils.addToWorldClock(amd);
                this.animationPlay();
            }
        }

        public stop(){
            if(this.hasDisposed || !this._armatureDisplay) return;
            let amd = this._armatureDisplay;
            if(amd.armature) {
                amd.animation.stop();
                DisplayUtils.removeFromWorldClock(amd);
            }
        }

        public addToGObject(target:GObject,idx?:number){
            if(this.hasDisposed) return;
            if(idx!=undefined)
                (<DisplayObjectContainer>target.displayObject).addChildAt(this,idx);
            else
                (<DisplayObjectContainer>target.displayObject).addChild(this);
        }

        private animationPlay(){
            let armature = this._armatureDisplay;
            if(!armature.parent){
                this.addChild(armature);
            }
            if(armature.armature){
                armature.animation.timeScale = this._speed;
                armature.animation.play(this._playAnimation, this._playTimes);
            }
        }

        get hasDisposed():boolean{
            return !this._skeleton;
        }

        public onGotArmature(callBack:(dis?:EgretArmatureDisplay, autoEft?:SkeletonAutoEffect)=>void, callObj:any){
            if(!this._onGotArmature){
                this._onGotArmature = new BackCall();
            }
            this._onGotArmature.reset(callBack, callObj);
        }
    }
}